using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using FarseerGames.FarseerPhysics.Collisions;
using FarseerGames.FarseerPhysics.Dynamics;
using System.Threading;

namespace StupidSpaceThing
{
	internal class Map
	{
		public const float MinHeight = -4.9f;
		public const float MaxHeight = 7 * 0.8f;
		public static Vector3 MaxHeightOffset { get { return new Vector3(0, MaxHeight, 0); } }
		public static float MidHeight;

		public readonly int Width;
		public readonly int Height;
		public readonly float CellSize, HalfCellSize;
		public Vector3 TopLeft, TopRight, BottomLeft, BottomRight, Center;
        public VertexPositionColorTexture[] Vertices;
		public int[] Indices;
		public VertexDeclaration VertexDeclaration;
		public readonly int PrimitiveCount;
		private Cell[,] cells;
        static public Color DefaultColor = new Color(new Vector4(0.6f,0.3f,0.6f,0.7f));
        private TimeSpan bombQueueTime = TimeSpan.Zero;
		private Queue<BombPayload> bombQueue = new Queue<BombPayload>();
		private Stack<BombPayload> bombPool;
		public int BombQueue { get { return bombQueue.Count; } }
		public int BombPool { get { return bombPool.Count; } }
		private Thread thread;
        private Effect effect;
        private Texture2D point;
        private Random random;
        private SpriteBatch spriteBatch;
        private GraphicsDevice device;

		private RenderTarget2D bombTarget;
		private Texture2D bombTexture;
		private Color[] bombMap;
		
		public Map(GraphicsDevice device, int width, int height, float cellSize) {

			MidHeight = (MaxHeight + MinHeight) / 2.0f;
			this.Width = width;
			this.Height = height;
			this.CellSize = cellSize;
			this.HalfCellSize = cellSize / 2.0f;
            this.device = device;

			bombMap = new Color[Width * Height];

            random = new Random();

			bombTarget = new RenderTarget2D(device, Width, Height, 1, SurfaceFormat.Color, MultiSampleType.None, 0);

            spriteBatch = new SpriteBatch(device);

			bombPool = new Stack<BombPayload>();
			for( int b = 0; b < 100; b++ ) {
				bombPool.Push(new BombPayload());
			}


			TopLeft = new Vector3(Width * CellSize, 0, Height * CellSize);
			TopRight = new Vector3(0, 0, Height * CellSize);
			BottomLeft = new Vector3(Width * CellSize, 0, 0);
			BottomRight = new Vector3(0, 0, 0);
			Center = new Vector3(Width * CellSize / 2, 0, Height * CellSize / 2);
			
			VertexDeclaration = new VertexDeclaration(device, VertexPositionColorTexture.VertexElements);
			// generate
			cells = new Cell[Width, Height];

            Vertices = new VertexPositionColorTexture[Width * Height * 4];
			Indices = new int[Width * Height * 6];
			PrimitiveCount = Indices.Length / 3;
			Random rand = new Random();			
			int i = 0, j = 0;
			Vector3[] tempVertices = new Vector3[8];
			// map boundary
			Body body = BodyFactory.Instance.CreateRectangleBody(Game1.Simulator, width * CellSize, 4, 10000000);
			body.Position = new Vector2(width * CellSize / 2, -2);
			body.IsStatic = true;
			Geom geom = GeomFactory.Instance.CreateRectangleGeom(Game1.Simulator, body, width * CellSize, 4);
			geom.RestitutionCoefficient = 1.0f;
			geom.FrictionCoefficient = 0.0f;
			body = BodyFactory.Instance.CreateRectangleBody(Game1.Simulator, width * CellSize, 4, 10000000);
			body.Position = new Vector2(width * CellSize / 2, height * CellSize + 2);
			body.IsStatic = true;
			geom = GeomFactory.Instance.CreateRectangleGeom(Game1.Simulator, body, width * CellSize, 4);
			geom.RestitutionCoefficient = 1.0f;
			geom.FrictionCoefficient = 0.0f;
			body = BodyFactory.Instance.CreateRectangleBody(Game1.Simulator, 4, height * CellSize, 10000000);
			body.Position = new Vector2(-2, height * CellSize / 2);
			body.IsStatic = true;
			geom = GeomFactory.Instance.CreateRectangleGeom(Game1.Simulator, body, 4, height * CellSize);
			geom.RestitutionCoefficient = 1.0f;
			geom.FrictionCoefficient = 0.0f;
			body = BodyFactory.Instance.CreateRectangleBody(Game1.Simulator, 4, height * CellSize, 10000000);
			body.Position = new Vector2(width * CellSize + 2, height * CellSize / 2);
			body.IsStatic = true;
			geom = GeomFactory.Instance.CreateRectangleGeom(Game1.Simulator, body, 4, height * CellSize);
			geom.RestitutionCoefficient = 1.0f;
			geom.FrictionCoefficient = 0.0f;

			for( int z = 0; z < Height; z++ ) {
				for( int x = 0; x < Width; x++ ){
					//float boxHeight = ((float)rand.NextDouble()) * heightDiff + MinHeight;
					float boxHeight = MidHeight;
					cells[x, z] = new Cell(x, z, boxHeight, cellSize, Vertices, Indices, i, j);
					i += 4;
					j += 6;
					//i += 20;
					//j += 30;
				}
			}
			for( int z = 0; z < Height; z++ ) {
				for( int x = 0; x < Width; x++ ) {
					List<Cell> neighbors = new List<Cell>();
					if( x > 0 ) neighbors.Add(cells[x - 1, z]);
					if( x < Width - 1 ) neighbors.Add(cells[x + 1, z]);
					if( z > 0 ) neighbors.Add(cells[x, z - 1]);
					if( z < Height - 1 ) neighbors.Add(cells[x, z + 1]);
					cells[x, z].Neighbors = neighbors.ToArray();
				}
			}

			thread = new Thread(new ThreadStart(flowProcess));
			thread.Start();
		}

		public void Clear() {
			for( int z = 0; z < Height; z++ ) {
				for( int x = 0; x < Width; x++ ) {
					cells[x, z].Occupier = null;
				}
			}
		}

		public void Stop() {
			thread.Abort();
		}

		public void StartBombing() {			
			TextureTools.Begin(bombTarget);
			//if( bombTexture != null ) {
			//	TextureTools.DrawTexture(bombTexture, 0.99f);
			//}
		}

		public void EndBombing() {
			bombTexture = TextureTools.End();
			bombTexture.GetData<Color>(bombMap);
		}

		public void Bomb(RealGameTime gameTime, Vector2 position2D, float force, FactionEntity entity) {
			Bomb(gameTime, position2D, force, Map.MidHeight - 3, entity);
		}

		public void Bomb(RealGameTime gameTime, Vector2 position2D, float force, float limit, FactionEntity entity) {

			if( force == 0) { return; }
            if (bombQueueTime == TimeSpan.Zero) { bombQueueTime = gameTime.TotalRealGameTime; }
            else if (gameTime.TotalRealGameTime.CompareTo(bombQueueTime) != 0) { return; }

            lock( bombQueue ) {
				BombPayload bomb = GetBombPayload(position2D, force, limit);
				if( bomb != null ){
					bombQueue.Enqueue(bomb);
				}
			}
		}
        public void LoadEffect(Effect effect)
        {
            this.effect = effect;
        }
        public void LoadTextures(Texture2D point)
        {
            
            this.point = point;
        }
        public void Draw(Camera camera)
        {
            effect.Parameters["World"].SetValue(Matrix.Identity);
            effect.Parameters["View"].SetValue(camera.View);
            effect.Parameters["Projection"].SetValue(camera.Projection);
            effect.Parameters["ColorTexture"].SetValue(bombTexture);
            effect.Parameters["Height"].SetValue(Height);
            effect.Parameters["Width"].SetValue(Width);
            effect.Parameters["CellSize"].SetValue(CellSize);
            effect.Parameters["Texture"].SetValue(ShaderSystem.animatedTexture.Texture);

            device.VertexDeclaration = this.VertexDeclaration;

            effect.Begin();
            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                pass.Begin();
                device.DrawUserIndexedPrimitives<VertexPositionColorTexture>(PrimitiveType.TriangleList, this.Vertices, 0, this.Vertices.Length, this.Indices, 0, this.PrimitiveCount);
                pass.End();
            }
            effect.End();
        }

		public void DrawMinimap() {
            
			if( bombTexture != null ) {
				spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Texture, SaveStateMode.SaveState);
				spriteBatch.Draw(bombTexture, new Vector2(bombTexture.Width / 2, bombTexture.Height / 2), null, Color.White, (float)Math.PI, new Vector2(bombTexture.Width / 2, bombTexture.Height / 2), 1, SpriteEffects.None, 0);
                //spriteBatch.Draw(TextureTools.Circle, new Vector2(0, 2 * 64), Color.White);
                /*
                if (RandomTexture != null)
                {
                    spriteBatch.Draw(RandomTexture, new Vector2(0, bombTexture.Height), Color.White);
                }
                spriteBatch.Draw(TextureTools.Circle, new Vector2(0, 2 * 64), Color.White);
                spriteBatch.Draw(TextureTools.Gauss, new Vector2(0, 3 * 64), Color.White);

                spriteBatch.Draw(animatedTest.Texture, new Vector2(0, 4 * 64), Color.White);
                spriteBatch.Draw(animatedTest.Texture, new Vector2(64, 4 * 64), Color.White);
                spriteBatch.Draw(animatedTest.Texture, new Vector2(0, 5 * 64), Color.White);
                spriteBatch.Draw(animatedTest.Texture, new Vector2(64, 5 * 64), Color.White);
                */
                spriteBatch.End();
			}            
		}

		public void BombProcess() {
			Queue<BombPayload> curQueue = null;
			lock( bombQueue ) {
				curQueue = bombQueue;
				bombQueue = new Queue<BombPayload>();
                bombQueueTime = TimeSpan.Zero;
			}
			if( curQueue.Count > 0 ) {
				while( curQueue.Count > 0 ) {
					BombPayload payload = curQueue.Dequeue();
					float xf = (payload.Position2D.X + HalfCellSize) / CellSize;
					float zf = (payload.Position2D.Y + HalfCellSize) / CellSize;
					int x = (int)Math.Floor(xf);
					int z = (int)Math.Floor(zf);
					TextureTools.DrawGauss(x, z, (int)(payload.Force * 2), Color.White); // 5 = 2% of 255
					bombPool.Push(payload);
				}
			}
		}
		
		private void flowProcess() {
			#if XBOX
			thread.SetProcessorAffinity(3);
			#endif

			while( true ) {
								
				foreach( Cell cell in cells ) {
					cell.Flow();
				}
				Thread.Sleep(30);
			}

			/*while( true ) {
				Queue<BombPayload> curQueue = null;
				lock( bombQueue ) {
					curQueue = bombQueue;
					bombQueue = new Queue<BombPayload>();				
				}
				if( curQueue.Count > 0 ) {
					while( curQueue.Count > 0 ) {
						BombPayload payload = curQueue.Dequeue();
						float xf = (payload.Position2D.X - HalfCellSize) / CellSize;
						float zf = (payload.Position2D.Y - HalfCellSize) / CellSize;
						int x = (int)Math.Floor(xf);
						int z = (int)Math.Floor(zf);
						int dist = (int)payload.Force / 5;
						if( dist < 4 ) dist = 4;
						for( int i = x - dist; i < x + dist; i++ ) {
							if( i < 0 || i >= Width ) continue;
							for( int j = z - dist; j < z + dist; j++ ) {
								if( j < 0 || j >= Height ) continue;
								float manhattenDistance = (float)Math.Pow((Math.Abs(i - xf) + Math.Abs(j - zf)), 2);
								if( manhattenDistance < 1 ) manhattenDistance = 1f;
								float curForce = (-payload.Force / manhattenDistance) + Map.MidHeight; // (Game1.Random.Next(9,12) / 10.0f))
								if( curForce < cells[i, j].Direction ) {
									cells[i, j].Direction = curForce;
									if( cells[i, j].Direction < payload.Limit ) {
										cells[i, j].Direction = payload.Limit;
									}
								}
							}
						}
					}
					Flow();
				}
				Thread.Sleep(10);
			}*/
		}

		private BombPayload GetBombPayload(Vector2 position2D, float force, float limit) {
			if( bombPool.Count == 0 ) return null;
			BombPayload bomb = bombPool.Pop();
			bomb.Position2D = position2D;
			bomb.Force = force;
			bomb.Limit = limit;
			return bomb;
		}

		private class BombPayload
		{
			public Vector2 Position2D;
			public float Force;
			public float Limit;

			public BombPayload() { }
		}

		public void Flow() {			
			lock( Game1.CurMap ) {
				bool inProgress = TextureTools.DrawInProgress;
				
				int index = 0;
				for( int z = 0; z < Height; z++ ) {
					for( int x = 0; x < Width; x++ ) {
						cells[x, z].Direction = -bombMap[index].R / 50.0f;
						index++;
					}
				}
			}
		}

		public Cell GetCell(FactionEntity entity) {
			return GetCell(entity.Position);
		}

		public Cell GetCell(Vector2 Position2D) {
			return GetCell(new Vector3(Position2D.X, 0, Position2D.Y));
		}

		public Cell GetCell(Vector3 Position) {
			float xf = (Position.X) / CellSize;
			float zf = (Position.Z) / CellSize;
			int x = (int)Math.Floor(xf);
			int z = (int)Math.Floor(zf);
			if( x < 0 ) x = 0;
			if( z < 0 ) z = 0;
			if( x >= Width ) x = Width - 1;
			if( z >= Height ) z = Height - 1;
			return cells[x, z];
		}

		public Cell Occupy(Unit unit) {
			Cell cell = GetCell(unit);
			if( cell.Occupier == null ) {
				cell.Occupier = unit;
				return cell;
			}
			return null;
		}

		public void Occupy(FactionEntity entity, bool inverse) {
			Cell cell = GetCell(entity);
			int area = 0;
			if( entity.Entity.ColObject is ColCircle ) {
				ColCircle colCircle = entity.Entity.ColObject as ColCircle;
				area = (int)(colCircle.Radius / CellSize);
			} else if( entity.Entity.ColObject is ColRect ) {
				ColRect colRect = entity.Entity.ColObject as ColRect;
				area = (int)((colRect.Width / 2) / CellSize);				
			}
			for( int i = cell.X - area; i <= cell.X + area; i++ ) {
				if( i < 0 || i >= Width ) continue;
				for( int j = cell.Z - area; j <= cell.Z + area; j++ ) {
					if( j < 0 || j >= Height ) continue;
					if( inverse ) {
						cells[i, j].Occupier = null;
					} else {
						cells[i, j].Occupier = entity;
					}
				}
			}
		}

		public Cell GetFreeCell() {
			return GetFreeCell(0, Width, 0, Height);
		}

		public Cell GetFreeCell(Vector3 Position, int cellRadius) {
			Cell posCell = GetCell(Position);
			return GetFreeCell(posCell.X - cellRadius, posCell.X + cellRadius, posCell.Z - cellRadius, posCell.Z + cellRadius);
		}

		public Cell GetFreeCell(int fromX, int toX, int fromZ, int toZ) {
			if( fromX < 1 ) fromX = 1;
			if( toX > Width - 1 ) toX = Width - 1;
			if( fromZ < 1 ) fromZ = 1;
			if( toZ > Height - 1 ) toZ = Height - 1;
			while( true ) {
				int x = Game1.Random.Next(fromX, toX);
				int z = Game1.Random.Next(fromZ, toZ);
				if( cells[x, z].Occupier == null ) {
					return cells[x, z];
				}
			}
		}

		public LinkedList<Cell> GetPath(Vector3 start, Vector3 end) {
			throw new ApplicationException("definitely not yet working");
			Cell startCell = GetCell(start);
			Cell endCell = GetCell(end);			
			for( int z = 0; z < Height; z++ ) {
				for( int x = 0; x < Width; x++ ) {
					cells[x, z].AStarValue = -1;
				}
			}
			LinkedList<Cell> path = new LinkedList<Cell>();
			LinkedList<Cell> sortedCells = new LinkedList<Cell>();
			Cell curCell = startCell;
			startCell.AStarValue = 0;			
			while( true ) {
				if( curCell == endCell ){
					return path;
				}
				Cell[] neighbors = curCell.Neighbors;
				foreach( Cell neighbor in neighbors ) {					
					if( neighbor.AStarValue == -1 ) {
						neighbor.AStarValue = curCell.AStarValue + 1;
						if( sortedCells.Count == 0 ) {
							sortedCells.AddFirst(neighbor);
						} else {
							LinkedListNode<Cell> curSortedCell = sortedCells.First;
							while( curSortedCell != null && curSortedCell.Value.AStarValue < neighbor.AStarValue ) {
								curSortedCell = curSortedCell.Next;
							}
							if( curSortedCell == null ) {
								sortedCells.AddLast(neighbor);
							} else {
								sortedCells.AddBefore(curSortedCell, neighbor);
							}
						}
					}
				}

			}
		}

		private readonly int step = 1;
		public Vector2? CheckCollision(Vector2 v0, Vector2 v1) {
			Cell p0 = GetCell(v0);
			Cell p1 = GetCell(v1);
			if( p0.X < 0 || p0.X >= Width ||
				p0.Z < 0 || p0.Z >= Height )
				return null;
			// init
			int x0 = (int)p0.X;
			int x1 = (int)p1.X;
			int y0 = (int)p0.Z;
			int y1 = (int)p1.Z;
			int width = Width;
			int height = Height;
			// check collision with objects
			int tmp;
			bool steep = Math.Abs(y1 - y0) > Math.Abs(x1 - x0);
			if( steep ) {
				// swap(x0, y0)
				tmp = x0;
				x0 = y0;
				y0 = tmp;
				// swap(x1, y1)
				tmp = x1;
				x1 = y1;
				y1 = tmp;
				// swap width, height
				tmp = width;
				width = height;
				height = tmp;
			}
			bool pointsSwapped = false;
			if( x0 > x1 ) {
				pointsSwapped = true;
				// swap(x0, x1)
				tmp = x0;
				x0 = x1;
				x1 = tmp;
				// swap(y0, y1)
				tmp = y0;
				y0 = y1;
				y1 = tmp;
			}
			int deltax = (x1 - x0) * step;
			int deltay = Math.Abs(y1 - y0) * step;
			int error = -deltax / 2;
			int ystep;
			if( y0 < y1 )
				ystep = 1 * step;
			else
				ystep = -1 * step;
			if( !pointsSwapped ) {
				int y = y0;
				for( int x = x0; x <= x1 && x < width; x += step ) {
					if( y < 0 || y >= height )
						break;
					if( steep ) {
						if( cells[y, x].Occupier != null && x != p0.X && y != p0.Z ) {
							return new Vector2(y, x);
						}
					} else {
						if( cells[x, y].Occupier != null && x != p0.X && y != p0.Z ) {
							return new Vector2(x, y);
						}
					}
					error = error + deltay;
					if( error > 0 ) {
						y = y + ystep;
						error = error - deltax;
					}
				}
			} else {
				int y = y1;
				for( int x = x1; x >= x0 && x >= 0; x -= step ) {
					if( y < 0 || y >= height )
						break;
					if( steep ) {
						if( cells[y, x].Occupier != null && x != p0.X && y != p0.Z ) {
							return new Vector2(y, x);
						}
					} else {
						if( cells[x, y].Occupier != null && x != p0.X && y != p0.Z ) {
							return new Vector2(x, y);
						}
					}
					error = error + deltay;
					if( error > 0 ) {
						y = y - ystep;
						error = error - deltax;
					}
				}
			}
			// nothing
			return null;
		}

		internal class Cell
		{
			public readonly int X, Z;
			public float Height;
			private float size;
            private VertexPositionColorTexture[] vertices;
			private int[] indices;
			private int vertexOffset;
			private int indexOffset;
			private Vector3[] tempVertices = new Vector3[8];
			private static Vector2 textureUpperLeft = new Vector2(1.0f, 1.0f);
			private static Vector2 textureUpperRight = new Vector2(0.0f, 1.0f);
			private static Vector2 textureLowerLeft = new Vector2(1.0f, 0.0f);
			private static Vector2 textureLowerRight = new Vector2(0.0f, 0.0f);
			private bool inited = false;
			public float Direction = 0.0f;
			public Cell[] Neighbors;
			public int AStarValue = -1;
			public int ManhattenDistance(Cell other) {
				return (int)Math.Abs(X - other.X) + (int)Math.Abs(Z - other.Z);
			}
			private FactionEntity occupier;
			public FactionEntity Occupier {
				get { return occupier; }
				set {
					occupier = value;
					/*if( occupier != null ) {
						vertices[vertexOffset + 0].Color = occupier.Faction.Color;
						vertices[vertexOffset + 1].Color = occupier.Faction.Color;
						vertices[vertexOffset + 2].Color = occupier.Faction.Color;
						vertices[vertexOffset + 3].Color = occupier.Faction.Color;
					} else {
						vertices[vertexOffset + 0].Color = DefaultColor;
						vertices[vertexOffset + 1].Color = DefaultColor;
						vertices[vertexOffset + 2].Color = DefaultColor;
						vertices[vertexOffset + 3].Color = DefaultColor;
					}*/
				}
			}

            public Cell(int x, int z, float height, float size, VertexPositionColorTexture[] vertices, int[] indices, int vertexOffset, int indexOffset)
            {
				this.X = x;
				this.Z = z;
				this.Height = height;
				this.size = size;
				this.vertices = vertices;
				this.indices = indices;
				this.vertexOffset = vertexOffset;
				this.indexOffset = indexOffset;
				tempVertices[4] = new Vector3(x * size, 0, z * size);
				tempVertices[5] = new Vector3((x + 1) * size, 0, z * size);
				tempVertices[6] = new Vector3((x + 1) * size, 0, (z + 1) * size);
				tempVertices[7] = new Vector3(x * size, 0, (z + 1) * size);
				Generate();
				inited = true;
			}

			private const float movement = 0.1f;
			public void Flow() {
				Direction += movement;
				if( Direction > Map.MidHeight ) {
					Direction = Map.MidHeight;
				}
				if( Direction < Map.MinHeight ) {
					Direction = Map.MinHeight;
				}
				if( Height < Direction ) {
					Height += movement;
					if( Height > Direction ) {
						Height = Direction;
					}
				} else {
					Height -= movement;
					if( Height < Direction ) {
						Height = Direction;
					}
				}
				updateHeight();
			}

			private void updateHeight() {
				vertices[vertexOffset + 0].Position.Y = Height;
				vertices[vertexOffset + 1].Position.Y = Height;
				vertices[vertexOffset + 2].Position.Y = Height;
				vertices[vertexOffset + 3].Position.Y = Height;
			}

			public void Generate() {
				tempVertices[0] = new Vector3(X * size, Height, Z * size);
				tempVertices[1] = new Vector3((X + 1) * size, Height, Z * size);
				tempVertices[2] = new Vector3((X + 1) * size, Height, (Z + 1) * size);
				tempVertices[3] = new Vector3(X * size, Height, (Z + 1) * size);
				// top
				buildSide(tempVertices[0], tempVertices[1], tempVertices[2], tempVertices[3], DefaultColor, vertexOffset, indexOffset);
				// left
				//buildSide(tempVertices[0], tempVertices[3], tempVertices[7], tempVertices[4], Vector3.Left, vertexOffset + 4, indexOffset + 6);
				// front
				//buildSide(tempVertices[3], tempVertices[2], tempVertices[6], tempVertices[7], Vector3.Forward, vertexOffset + 8, indexOffset + 12);
				// right
				//buildSide(tempVertices[2], tempVertices[1], tempVertices[5], tempVertices[6], Vector3.Right, vertexOffset + 12, indexOffset + 18);
				// back
				//buildSide(tempVertices[1], tempVertices[0], tempVertices[4], tempVertices[5], Vector3.Backward, vertexOffset + 16, indexOffset + 24);
			}

			private void buildSide(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3, Color color, int vertexOffset, int indexOffset) {
                vertices[vertexOffset + 0] = new VertexPositionColorTexture(v0, color, textureLowerRight);
                vertices[vertexOffset + 1] = new VertexPositionColorTexture(v1, color, textureLowerLeft);
                vertices[vertexOffset + 2] = new VertexPositionColorTexture(v2, color, textureUpperLeft);
                vertices[vertexOffset + 3] = new VertexPositionColorTexture(v3, color, textureUpperRight);
				if( !inited ) {
					indices[indexOffset + 0] = vertexOffset + 0;
					indices[indexOffset + 1] = vertexOffset + 1;
					indices[indexOffset + 2] = vertexOffset + 2;
					indices[indexOffset + 3] = vertexOffset + 2;
					indices[indexOffset + 4] = vertexOffset + 3;
					indices[indexOffset + 5] = vertexOffset + 0;
				}
			}
		}

	}
}